#include "general.h"
#if (SENSOR_TYPE == Sensor_OV5610)
#include "pv_api.h"
#include "sensor_cdsp.h"
#include "sp1k_aaa_api.h"
#include "aaa_api.h"
#define HAL_FRONT_REMOVE_UNCALL_FUNCTION

// copy from ov3630, please modify this after you check the raw data of sensor.
UINT16 ctc_rgain[4]={217,310,384,0};
UINT16 ctc_bgain[4]={402,366,276,0};

//Flow 15
AECQ AECmdQue[3] ={
							{1,2},
							{3,4},
							{5,6}
						};
//Flow 7
#if 1
code AEstr LVtbl60[128] =			 
{	{0,100,127,0},{1,100,125,0},{2,100,122,0},{3,100,118,0},
	{4,100,116,0},{5,100,114,0},{6,100,112,0},{7,100,60,0},
	{8,100,56,0},{9,100,54,0},{10,120,58,0},{11,120,56,0},
	{12,120,53,0},{13,120,51,0},{14,120,49,0},{15,120,28,0},
	{16,150,52,0},{17,150,50,0},{18,150,48,0},{19,200,55,0},
	{20,200,52,0},{21,200,50,0},{22,200,48,0},{23,200,26,0},
	{24,200,24,0},{25,200,21,0},{26,200,20,0},{27,200,18,0},
	{28,200,16,0},{29,200,13,0},{30,200,10,0},{31,200,8,0},
	{32,200,6,0},{33,300,18 ,0},{34,300,14 ,0},{35,300,12,0},
	{36,300,10,0},{37,300,8,0},{38,300,6,0},{39,600,25,0},
	{40,600,22,0},{41,600,21,0},{42,600,18,0},{43,600,17,0},
	{44,600,13,0},{45,600,11,0},{46,600,9,0},{47,600,7,0},
	{48,600,5,0},{49,1195,27,0},{50,1195,25,0},{51,1195,22,0},
	{52,1195,20,0},{53,1195,18,0},{54,1195,17,0},{55,1195,14,0},
	{56,1195,12,0},{57,1195,9,0},{58,1195,7,0},{59,1372,8,0},
	{60,1470,8,0},{61,1576,8,0},{62,1689,8,0},{63,1811,8,0},
	{64,1934,8,0},{65,2080,8,0},{66,2228,8,0},{67,2390,8,0},
	{68,2561,8,0},{69,2745,8,0},{70,2941,8,0},{71,3153,8,0},
	{72,3379,8,0},{73,3622,8,0},{74,3869,8,0},{75,4161,8,0},
	{76,4456,8,0},{77,4780,8,0},{78,5123,8,0},{79,5446,8,0},
	{80,5656,8,0},{81,6307,8,0},{82,6759,8,0},{83,7245,8,0},
	{84,7739,8,0},{85,8322,8,0},{86,8919,8,0},{87,9559,8,0},
	{88,10246,8,0},{89,10981,8,0},{90,11769,8,0},{91,12614,8,0},
	{92,14705,10,0},{93,16339,11,0},{94,16339,9,0},{95,18382,11,0},
	{96,18382,9,0},{97,18382,7,0},{98,21008,9,0},{99,21008,7,0},
	{100,21008,5,0},{101,24509,7,0},{102,24509,6,0},{103,29411,8,0},
	{104,29411,7,0},{105,29411,5,0},{106,29411,4,0},{107,36764,7,0},
	{108,36764,6,0},{109,36764,4,0},{110,49019,9,0},{111,49019,7,0},
	{112,49019,6,0},{113,49019,4,0},{114,73529,12,0},{115,73529,11,0},
	{116,73529,9,0},{117,73529,7,0},{118,73529,6,0},{119,73529,4,0},
	{120,147058,19,0},{121,147058,17,0},{122,147058,16,0},{123,147058,14,0},
	{124,147058,12,0},{125,147058,11,0},{126,147058,9,0},{127,147058,7,0}};

code AEstr LVtbl50[125] =
{	{0,100,119,0},{1,100,117,0},{2,100,115,0},{3,100,113,0},{4,100,62,0},
	{5,100,58,0},{6,100,56,0},{7,100,53,0},{8,100,51,0},{9,125,56,0},
	{10,125,52,0},{11,125,51,0},{12,166,59,0},{13,166,56,0},{14,166,54,0},
	{15,166,52,0},{16,166,50,0},{17,200,53,0},{18,200,51,0},{19,200,49,0},
	{20,200,28,0},{21,200,26,0},{22,200,23,0},{23,200,21,0},{24,200,19,0},
	{25,200,18,0},{26,200,16,0},{27,200,13,0},{28,200,10,0},{29,200,7,0},
	{30,200,4,0},{31,333,17,0},{32,333,16,0},{33,333,12,0},{34,333,9,0},
	{35,333,8,0},{36,500,21,0},{37,500,19,0},{38,500,17,0},{39,500,16,0},
	{40,500,12,0},{41,500,10,0},{42,500,8,0},{43,1000,28,0},{44,1000,25,0},
	{45,1000,22,0},{46,1000,21,0},{47,1000,19,0},{48,1000,17,0},{49,1000,16,0},
	{50,1000,12,0},{51,1000,10,0},{52,1000,8,0},{53,1055,8,0},{54,1131,8,0},
	{55,1212,8,0},{56,1299,8,0},{57,1392,8,0},{58,1492,8,0},{59,1600,8,0},
	{60,1714,8,0},{61,1837,8,0},{62,1969,8,0},{63,2111,8,0},{64,2262,8,0},
	{65,2425,8,0},{66,2599,8,0},{67,2785,8,0},{68,2985,8,0},{69,3199,8,0},
	{70,3429,8,0},{71,3675,8,0},{72,3939,8,0},{73,4222,8,0},{74,4525,8,0},
	{75,4850,8,0},{76,5198,8,0},{77,5571,8,0},{78,5971,8,0},{79,6399,8,0},
	{80,6859,8,0},{81,7351,8,0},{82,7879,8,0},{83,8444,8,0},{84,9050,8,0},
	{85,9700,8,0},{86,10396,8,0},{87,11143,8,0},{88,11942,8,0},{89,12800,8,0},
	{90,14705,10,0},{91,14705,8,0},{92,16339,9,0},{93,18382,10,0},{94,18382,8,0},
	{95,21008,10,0},{96,24509,12,0},{97,24509,10,0},{98,24509,8,0},{99,29411,12,0},
	{100,29411,10,0},{101,29411,8,0},{102,36764,12,0},{103,36764,10,0},{104,36764,8,0},
	{105,49019,14,0},{106,49019,12,0},{107,49019,10,0},{108,49019,8,0},{109,49019,7,0},
	{110,49019,5,0},{111,73529,14,0},{112,73529,12,0},{113,73529,10,0},{114,73529,8,0},
	{115,73529,7,0},{116,73529,5,0},{117,73529,4,0},{118,147058,19,0},{119,147058,17,0},
	{120,147058,16,0},{121,147058,14,0},{122,147058,12,0},{123,147058,10,0},{124,147058,8,0}};

#endif


void  HAL_OVI2C_Write(UINT8 RegAddr, UINT8 RegData)
{
  UINT8 reg_addr[1], reg_data[1];
  reg_addr[0] = RegAddr;
  reg_data[0] = RegData;
  HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);  //Set Seq SSC Write
}



void  HAL_FrontInit (UINT8 CamMode) USING_0
{
  printf (" Initialize the Front : Enter !!,CamMode=%d \n",CamMode);

  HAL_SetFrontIOConfig(0x00, 0x00, 0x04, 0x00);
  HAL_SetFrontCLKSource(0, 1);
  HAL_SetFrontCLKSet(1, 1, 0);
  HAL_SSCConfig(Sensor_Slave_Address, Sensor_SSC_Freq);
  XBYTE[0x2AB0] = 0x01;		      //Reset Sensor interface
  XBYTE[0x2AB0] = 0x00; 
  HAL_SensorRegInit();

  printf (" Initialize the Front : Exit !! \n");
}

void  HAL_FrontPreviewSet(void) USING_0
{
  //HAL_SetFrontReshape(4, 8, 1 , 1, 2, 1);
 // HAL_SetFrontImgCrop(276, 4, Sensor_Preview_HSize, Sensor_Preview_VSize, 0x00);  

  HAL_SetFrontImgCrop(Sensor_Preview_HOffset, Sensor_Preview_VOffset, Sensor_Preview_HSize, Sensor_Preview_VSize, 0x00);  
  HAL_SetFrontReshape(Sensor_Preview_Hfall, Sensor_Preview_Hrise, Sensor_Preview_HReshen, Sensor_Preview_Vfall, Sensor_Preview_Vrise, Sensor_Preview_VReshen);
	HAL_SetSensorPreview();

}




void  HAL_SensorRegInit(void)	
{

  HAL_Wait(20);
  //Use SSC to initializes CMOS sensor register///////////////////////////////////
  HAL_OVI2C_Write(0x12,0x80);
  HAL_Wait(1);
  HAL_OVI2C_Write(0x12,0x20);
  HAL_OVI2C_Write(0x13,0xC0);
  HAL_OVI2C_Write(0x00,0x00);
  HAL_OVI2C_Write(0x01,0x80);
  HAL_OVI2C_Write(0x02,0x80);
  HAL_OVI2C_Write(0x09,0x00);
  HAL_OVI2C_Write(0x0D,0x31);
  HAL_OVI2C_Write(0x0F,0x42);
  HAL_OVI2C_Write(0x14,0xC6);
  HAL_OVI2C_Write(0x15,0x02);
  HAL_OVI2C_Write(0x35,0x48);
  HAL_OVI2C_Write(0x36,0x20);
  HAL_OVI2C_Write(0x37,0x00);
  HAL_OVI2C_Write(0x38,0xD3);
  HAL_OVI2C_Write(0x39,0x00);
  HAL_OVI2C_Write(0x3B,0x18);
  HAL_OVI2C_Write(0x3C,0x1F);
  HAL_OVI2C_Write(0x44,0x00);
  HAL_OVI2C_Write(0x49,0x19);
  HAL_OVI2C_Write(0x4b,0x08);
  HAL_OVI2C_Write(0x4c,0x30);
  HAL_OVI2C_Write(0x4d,0x00);
  HAL_OVI2C_Write(0x4e,0x0f);
  HAL_OVI2C_Write(0x4F,0x0A);
  HAL_OVI2C_Write(0x50,0x4f);
  HAL_OVI2C_Write(0x11,0x80); 

}



void HAL_SetSensorPreview(void) USING_0
{
  /*maximum Exposure for OV5610 VGA resolution */

  HAL_OVI2C_Write(0x10,0x0D);  
  HAL_OVI2C_Write(0x04,0x00);
  HAL_OVI2C_Write(0x17,0x14);
  HAL_OVI2C_Write(0x18,0x64);
  HAL_OVI2C_Write(0x1B,0x00);
  HAL_OVI2C_Write(0x03,0x4A);
  HAL_OVI2C_Write(0x32,0x24);
  HAL_OVI2C_Write(0x33,0x1B);
  HAL_OVI2C_Write(0x34,0x5A);
  HAL_OVI2C_Write(0x48,0x00);
  HAL_OVI2C_Write(0x12,0x20);
  
  // HAL_FrontInputGate(0x00); // YG tune zoom control flow
}


void  HAL_FrontSnapSet(UINT16 Hsize,UINT16 Vsize) USING_0
{
	HAL_SetFrontReshape(Sensor_Snap_Hfall, Sensor_Snap_Hrise, Sensor_Snap_HReshen, Sensor_Snap_Vfall, Sensor_Snap_Vrise, Sensor_Snap_VReshen);
    HAL_SetFrontImgCrop(Sensor_Snap_HOffset, Sensor_Snap_VOffset, Hsize, Vsize, 1);
}

/**************************************************************************************
*                                                                                     *
*  Function Name : HAL_FrontGainSet                                                     *
*                                                                                     *
*  Purposes      :                                                                    *
*    To control Sensor gain                                                           *
*                                                                                     *
*  Desprictions  :                                                                    *
*    Adjust gain value for sensor                                                     *
*                                                                                     *
*  Arguments     :                                                                    *
*    value : in, gain value to set                                                    *
*    option : in, 0 -> immediate change value                                         *
*                 1 -> synchronize the value to the next Vsync                        *
*                                                                                     *
*  Returns       :                                                                    *
*    Error message                                                                    *
*                                                                                     *
*  See also      :                                                                    *
*                                                                                     *
***************************************************************************************/

UINT8 HAL_FrontGainSet(
    UINT32 value,
    UINT32  option
)
{
	UINT32 tmp0;
	UINT8 regaddr[1], regdata[1];


	tmp0 = option & 0x01;                 /* Sync VD ? */
	regaddr[0] = 0x00;
	regdata[0] = value;
	HAL_WriteSSC(regaddr, regdata, 0x01, tmp0);
	printf("Gain = %x\n",value);

	return SUCCESS;
}

/**************************************************************************************
*                                                                                     *
*  Function Name : HAL_FrontExpTimeSet                                                  *
*                                                                                     *
*  Purposes      :                                                                    *
*    To control exposure time                                                         *
*                                                                                     *
*  Desprictions  :                                                                    *
*    Adjust exposure time value                                                       *
*                                                                                     *
*  Arguments     :                                                                    *
*    value : in, expossure time value to set, unit 0.1ms                              *
*    option : in, 0 -> immediate change value                                         *
*                 1 -> synchronize the value to the next Vsync                        *
*                                                                                     *
*  Returns       :                                                                    *
*    Error message                                                                    *
*                                                                                     *
*  See also      :                                                                    *
*                                                                                     *
***************************************************************************************/
UINT32
HAL_FrontExpTimeSet(
	UINT32 value,
	UINT32 option
)
{
	UINT16 ltotal, ftotal, espline;
	UINT32 pixclk, tmp0;
	UINT8  regaddr[4], regdata[4];



	ltotal = Sensor_Preview_LineTotal;                        /* Read line total */
	ftotal = Sensor_Preview_FrameTotal;                       /* Read frame total */
	pixclk = 4000000;
	
	printf("ftotal = %x \n", ftotal);
	printf("ltotal = %x \n", ltotal);
	printf("pixclk = 0x%lx\n",pixclk);
	
	espline = (pixclk * 10) / (ltotal * value);
	option = option & 0x01; 


	printf("espline = %x \n", espline);



	if (espline >= ftotal ) {
		tmp0 =espline-ftotal;
	}
	else
	{
	    tmp0 =0;
	}

	regaddr[0] = 0x10;
	regdata[0] = espline >> 3;
	regaddr[1] = 0x04;
	regdata[1] = (espline & 0x07) ;
       regaddr[2] = 0x2D;
   	regdata[2] = tmp0;
       regaddr[3] = 0x2E;
   	regdata[3] = tmp0 >> 8;
	HAL_WriteSSC(regaddr, regdata, 0x04, option | 0x02);

	return SUCCESS;
}
/**************************************************************************************
*                                                                                     *
*  Function Name : HAL_FrontFrameRateSet                                                *
*                                                                                     *
*  Purposes      :                                                                    *
*    To control Frame Rate                                                            *
*                                                                                     *
*  Desprictions  :                                                                    *
*    Adjust Frame rate for sensor                                                     *
*                                                                                     *
*  Arguments     :                                                                    *
*    value : in, frame rate value to set                                              *
*    option : in, 0 -> immediate change value                                         *
*                 1 -> synchronize the value to the next Vsync                        *
*                                                                                     *
*  Returns       :                                                                    *
*    Error message                                                                    *
*                                                                                     *
*  See also      :                                                                    *
*                                                                                     *
***************************************************************************************/

UINT32
HAL_FrontFrameRateSet(
    UINT32 value,
    UINT32 option
)
{
	UINT32 ltotal, ftotal;
	UINT32 pixclk, tmp0;
	//UINT32 espline;
	//UINT32 status;
	UINT8 regaddr[4], regdata[4];


    ltotal = Sensor_Preview_LineTotal;						  /* Read line total */
    ftotal = Sensor_Preview_FrameTotal; 					  /* Read frame total */
    pixclk = 4000000;
	option = option & 0x01;

    tmp0=pixclk/(ltotal * value);
	
	if (tmp0 >= ftotal ) {
		tmp0 =tmp0-ftotal;
	}
	else
	{
	    tmp0 =0;
	}

     regaddr[0] = 0x2D;
     regdata[0] = tmp0;
     regaddr[1] = 0x2E;
     regdata[1] = tmp0 >> 8;
     HAL_WriteSSC(regaddr, regdata, 0x02, option | 0x02);

	 return 0;
	
}
#if 0
//////////////////////////////////////////////////////////////////////////////////////////////
UINT8 HAL_SetFrameRate (UINT8 FrameRate, UINT8 Option) USING_0
{
  //PRINT_FRONT ("            Enter Set FrameRate = %d \n", (UINT16)FrameRate);

  //PRINT_FRONT ("            Exit Set FrameRate \n");
  return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
UINT8 HAL_SetExposureTime (UINT32 Number, UINT8 Option) USING_0
{
  //PRINT_FRONT ("            Enter HAL_SetExposureTime \n");

  //PRINT_FRONT ("            Exit HAL_SetExposureTime \n");
  return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
UINT8 HAL_AdjustGain(UINT16 Value, UINT8 Option) USING_0
{
  UINT8   option1;
  UINT8 reg_addr[1], reg_data[1];
  option1 = Option & 0x01;  		//Sequential mode, Sync VD ?
  if ((Value >= 0x40) || (Value < 0x08) ) {
    return 1;
  }
  reg_addr[0] = 0x00;
  reg_data[0] = (UINT8)Value;
  HAL_WriteSSC(reg_addr, reg_data, 1, option1);
  //PRINT_FRONT ("            Exit HAL_AdjustGain \n");
  return 0;
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////

UINT8 HAL_SnapRaw8(UINT8 mode, UINT8 opt) USING_0
{
    UINT8 reg_addr[1], reg_data[1];
//    if (SnapNum > 16)
//        return 1;

    reg_addr[0] = 0x12;  // COMH: QXGA mode (2048x1536), master mode
    reg_data[0] = 0x00;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);

    reg_addr[0] = 0x1a;
    reg_data[0] = 0xf4;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);

	reg_addr[0] = 0x17;
    reg_data[0] = 0x0f;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);

    reg_addr[0] = 0x18;
    reg_data[0] = 0xb3;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);

	reg_addr[0] = 0x19;
    reg_data[0] = 0x00;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);


    reg_addr[0] = 0x03;
    reg_data[0] = 0x44;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);

    
    reg_addr[0] = 0x1B;
    reg_data[0] = 0x01;
    HAL_WriteSSC(reg_addr, reg_data, 0x01, 0x00);
    
    HAL_FrontVdWait(0, 1);
    
//    XBYTE[0X2A10] = 0x10 | SnapNum;

  return 0;
}

#ifndef HAL_FRONT_REMOVE_UNCALL_FUNCTION
void HalSensorPrePV(
	void
)
{
	return;
}
#endif

#endif

